package com.tcoiss.webservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tcoiss.common.core.constant.Constants;
import com.tcoiss.common.core.enums.ErroEnums;
import com.tcoiss.common.core.exception.CustomException;
import com.tcoiss.common.log.annotation.ApiLog;
import com.tcoiss.common.log.enums.BusinessType;
import com.tcoiss.common.redis.service.RedisService;
import com.tcoiss.common.component.api.model.K3Result;
import com.tcoiss.webservice.apiServer.*;
import com.tcoiss.webservice.domain.ApiServiceConfig;
import com.tcoiss.webservice.domain.ApiTestVo;
import com.tcoiss.webservice.mapper.ApiServiceConfigMapper;
import com.tcoiss.webservice.service.IApiService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class ApiServiceImpl implements IApiService {

    @Autowired
    private ApiServiceConfigMapper apiServiceConfigMapper;

    @Autowired
    private HttpAPIServer httpAPIServer;

    @Autowired
    private RedisService redisService;

    private final static long EXPIRE_TIME = Constants.KD_TOKEN_EXPIRE * 90;

    @Override
    public Map<String, Object> apiTest(ApiTestVo vo)  {
        //todo 根据选择的id对创建0的挨个进行接口测试，测试成功的状态改为启用1
        //查询接口配置信息
        ApiServiceConfig serviceConfig = apiServiceConfigMapper.selectById(vo.getApiId());
        if(serviceConfig.getDataLevel() == 0){
            throw new CustomException(ErroEnums.DATAERRO.getCode(),new String[]{"查询ID为:"+ vo.getApiId()}
                    ,ErroEnums.DATAERRO.getInfo() + "接口配置未生效");
        }
        try {
            //初始化接口服务
            //解析请求参数param 转成Json对象
            JSONObject jsonObject = JSON.parseObject(vo.getParam());
            switch (serviceConfig.getAppName()){
                case "kingdee":
                    return executeKdByApiCode(serviceConfig.getApiCode(),jsonObject);
                case "gaode":
                    return executeByApiCode(serviceConfig.getApiCode(),jsonObject);
                case "k3cloud":
                    //return executeK3Cloud(serviceConfig.getApiCode(),jsonObject);
                    return null;
                default:
                    return executeByApiCode(serviceConfig.getApiCode(),jsonObject);
            }
        } catch (Exception e) {
            throw new CustomException(ErroEnums.APIERRO.getCode(),"API编码为:" + serviceConfig.getApiCode() + "接口测试异常",e);
        }

    }
    @ApiLog(title = "API调用" , businessType = BusinessType.EXECUTE_API)
    @Override
    public Map<String, Object> executeByApiCode(String apiCode, Object param) {
        QueryWrapper<ApiServiceConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("api_code",apiCode);
        queryWrapper.eq("data_level",1);
        //查询接口配置信息
        ApiServiceConfig serviceConfig = apiServiceConfigMapper.selectOne(queryWrapper);
        if(serviceConfig==null||serviceConfig.getDataLevel()!=1){
            throw new CustomException(ErroEnums.DATAERRO.getCode(),new Object[]{apiCode},ErroEnums.DATAERRO.getInfo() + "接口未配置或未启用");
        }
        Invoker invoker = new InvokerBuilder().buildInvoker(serviceConfig);
        InvokeContext context = new InvokeContext();
        context.setEndpoint(serviceConfig.getApiUrl());
        context.setOperationCode(serviceConfig.getApiCode());
        context.setRequestType(serviceConfig.getRequestType());
        context.setParameters(param);
        context.setDataType(serviceConfig.getDataType());
        try {
            return invoker.invoke(httpAPIServer,context);
        } catch (Exception e) {
            throw new CustomException(ErroEnums.APIERRO.getCode(),
                    serviceConfig.getApiCode()+"执行http请求时异常："+e.getMessage(), e);
        }

    }

    @Override
    public K3Result executeK3Cloud(String apiCode, Object param) {
        //调用登录金蝶接口
        Map<String, Object> loginJson = executeByApiCode("k3CloudLogin",new HashMap<>());
        Integer type = Integer.valueOf(loginJson.get("LoginResultType").toString());
        if(type==1){//登录成功
            Map<String, Object> json = executeByApiCode(apiCode,param);
            return getResult(JSON.toJSONString(json));
        }
        return null;
    }

    @ApiLog(title = "金碟API调用" , businessType = BusinessType.EXECUTE_API)
    @Override
    public Map<String, Object> executeKdByApiCode(String apiCode, Object param) {
        String token = getKdAccessToken();
        QueryWrapper<ApiServiceConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("api_code",apiCode);
        queryWrapper.eq("data_level",1);
        //查询接口配置信息
        ApiServiceConfig serviceConfig = apiServiceConfigMapper.selectOne(queryWrapper);
        if(serviceConfig==null||serviceConfig.getDataLevel()!=1){
            throw new CustomException(ErroEnums.DATAERRO.getCode(), new Object[]{apiCode},ErroEnums.DATAERRO.getInfo() + "接口未配置或未启用");
        }
        Invoker invoker = new InvokerBuilder().buildInvoker(serviceConfig);
        InvokeContext context = new InvokeContext();
        context.setEndpoint(serviceConfig.getApiUrl());
        context.setOperationCode(serviceConfig.getApiCode());
        context.setRequestType(serviceConfig.getRequestType());
        context.setParameters(param);
        context.setDataType(serviceConfig.getDataType());
        context.setAccessToken(token);
        context.setAppName(serviceConfig.getAppName());
        try {
            return  invoker.invoke(httpAPIServer,context);
        } catch (Exception e) {
            throw new CustomException(ErroEnums.APIERRO.getCode(),
                    serviceConfig.getApiCode()+"执行http请求时异常："+e.getMessage(), e);
        }

    }




    public String getKdAccessToken() {
        String accessToken = redisService.getCacheObject("kd_access_token");
        if(StringUtils.isEmpty(accessToken)){
            Map<String,Object> appMap = this.executeByApiCode("getAppToken",new HashMap<>());
            if(appMap.get("state").equals("success")){
                String appToken = (String)((Map)appMap.get("data")).get("app_token");
                Map<String,Object> param = new HashMap<>();
                param.put("appToken",appToken);
                Map<String,Object> accessMap = this.executeByApiCode("getUserToken",param);
                if(accessMap.get("state").equals("success")){
                    accessToken = (String)((Map)accessMap.get("data")).get("access_token");
                    redisService.setCacheObject("kd_access_token",accessToken,EXPIRE_TIME, TimeUnit.SECONDS);
                    return accessToken;
                }else{
                    throw new CustomException(ErroEnums.APIERRO.getCode(),new Object[] { "getUserToken" },ErroEnums.APIERRO.getInfo() + "获取用户令牌失败："+accessMap.get("message"));
                }
            }else{
                throw new CustomException(ErroEnums.APIERRO.getCode(),new Object[] { "getAppToken" },ErroEnums.APIERRO.getInfo() + "获取应用令牌失败："+appMap.get("message"));
            }
        }
        return accessToken;
    }


    private K3Result getResult(String result){
        JSONObject json= JSONObject.parseObject(result);
        JSONObject resultJson = JSONObject.parseObject(json.getString("Result"));
        java.lang.System.out.println(json.get("Result"));
        JSONObject responseJson = JSONObject.parseObject(resultJson.getString("ResponseStatus"));
        java.lang.System.out.println(responseJson.getString("Errors"));
        String k3Code = responseJson.getString("ErrorCode");
        boolean isSuccess = responseJson.getBoolean("IsSuccess");
        K3Result k3Result = new K3Result();
        if(isSuccess) {
            k3Result.setCode("0");
            k3Result.setErrorMsg("");
            String SuccessEntitys = responseJson.getString("SuccessEntitys").replace("[", "").replace("]", "");
            JSONObject entity = JSONObject.parseObject(SuccessEntitys);
            String number = entity.getString("Number");
            k3Result.setSuccessNumber(number);
        }else {
            String error = responseJson.getString("Errors").replace("[", "").replace("]", "");
            JSONObject errorsJson =  JSONObject.parseObject(error);
            String k3Msg = errorsJson.getString("Message");
            k3Result.setCode(k3Code);
            k3Result.setErrorMsg(k3Msg);
            k3Result.setSuccessNumber("");
        }
        return k3Result;
    }



}
